package han.fetch;

import com.han.http.client.paramter.RequestHeader;
import han.entity.FinanceProjectIdEntity;
import han.entity.FinanceProjectLabelEntity;
import han.exception.OtherException;
import han.parser.FinanceProjectIdParser;
import han.proof.Cookie;
import han.sql.InsertThread;
import han.sql.Operator;
import han.util.OtherTools;

import java.sql.Timestamp;
import java.util.List;
import java.util.Random;
import java.util.Set;

import static com.han.http.util.Print.printlnInfo;
import static han.fetch.FinanceProjectId.RESPONSE_CODE;

/**
 * @author: Han
 * @date: 2018/8/8 9:18
 * @dscription: 使用全部标签, 获取所有融资项目id
 */
public class FinanceProjectIdThread implements Runnable {
    /**
     * 同步锁
     */
    private final Object krLock;
    /**
     * 抓取对象
     */
    private Fetcher fetcher;
    /**
     * cookie
     */
    private Cookie cookie;
    private Operator operator;
    /**
     * 融资项目标签实体
     */
    private List<FinanceProjectLabelEntity> labelList;
    /**
     * 数据库插入线程
     */
    private InsertThread insertThread;

    FinanceProjectIdThread(Cookie cookie, List<FinanceProjectLabelEntity> labelList, InsertThread insertThread,
                           Object krLock) {
        this.cookie = cookie;
        this.labelList = labelList;
        this.insertThread = insertThread;
        this.krLock = krLock;
        fetcher = new Fetcher();
        operator = Operator.getInstance();
    }

    @Override
    public void run() {
        for (FinanceProjectLabelEntity labelEntity : labelList) {
            getProjectIdM(labelEntity);
        }
        insertThread.executeInsertFinanceProIdAtOnce();
    }


    /**
     * 获取融资机构id,并根据参数决定是否接着上次的页数下载
     *
     * @param labelEntity 标签
     */
    private void getProjectIdM(FinanceProjectLabelEntity labelEntity) {
        String label = labelEntity.getLabel().replace(" ", "%20");
        String labelHex = OtherTools.convertStringToUTF8(label);
        String rowUrlStr = "https://rong.36kr.com/api/mobi-investor/label_dict/industry/companys?ccid=&" +
                "labelName=" + labelHex + "&order=desc&";
        RequestHeader[] requestHeader = {
                new RequestHeader("User-Agent", "36kr-Tou-Android/4.1.2 (MI 6; Android 8.0.0; Scale/1920x1080)"),
                new RequestHeader("Cookie", cookie.getCookie()),
                new RequestHeader("Host", "rong.36kr.com"),
                new RequestHeader("Connection", "Keep-Alive"),
                new RequestHeader("Accept-Encoding", "gzip")
        };
        Random random = new Random();
        //一般超时时间
        int generalTimeout = 1000 * 20;
        //访问间隔
        int interval;
        int totalPages = 1;
        int startIndex = 1;
        //如果接着上次页数继续下载
        //获取上次抓取的位置,并+1
        //startIndex = labelEntity.getCurrentPage() + 1;
        for (int pageIndex = startIndex; pageIndex <= totalPages; pageIndex++) {
            String urlStr = rowUrlStr + "page=" + pageIndex + "&pageSize=20&type=hot_score&cities=";
            try {
                //访问链接,获取数据
                String jsonStr;
                synchronized (krLock) {
                    //同步锁,避免同时发出大量请求,也为了降低占用系统资源
                    jsonStr = fetcher.getInfoByGet(urlStr, requestHeader, generalTimeout, generalTimeout, null);
                    try {
                        Thread.sleep(random.nextInt(500));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (!jsonStr.contains(RESPONSE_CODE[0])) {
                    throw new OtherException("没有获取到正确的内容" + jsonStr);
                }
                //解析json字符串中的项目id,获取项目ID set
                Set<FinanceProjectIdEntity> projectIdEntitySet = FinanceProjectIdParser.getProjectIdM(jsonStr, labelEntity);
                //存储当前页数
                labelEntity.setCurrentPage(pageIndex);
                //设置总页数
                totalPages = labelEntity.getTotalPages();
                insertThread.insertInsertProjectId(projectIdEntitySet);
                printlnInfo(cookie.getLoginName() + ":" + label + "第" + pageIndex + "获取完成");
            } catch (OtherException e) {
                printlnInfo(cookie.getLoginName() + ":" + label + "第" + pageIndex + "获取失败");
                e.printStackTrace();
                //没有获取到数据,跳出
                break;
            } catch (Exception e) {
                printlnInfo(cookie.getLoginName() + ":未知原因," + label + "第" + pageIndex + "获取失败");
                e.printStackTrace();
            } finally {
                interval = random.nextInt(1000 * 3) + 1000 * 2;
                try {
                    Thread.sleep(interval);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //更新标签
        labelEntity.setLastRequestTime(new Timestamp(System.currentTimeMillis()));
        operator.updateFinanceProjectLabel(labelEntity);
    }
}
